// API_Test1.cpp : Defines the entry point for the console application.
//

#if 1

#include <iostream>
#include "stdafx.h"
#include "SDL.h"

#include "tank.h"
#include "GraphicsManager.h"
#include "RenderingManager.h"
#include "ObjectManager.h"
#include "ResourceManager.h"

#include "LuaHandler.h"

using namespace std;

ObjectManager* om;

int _tmain(int argc, _TCHAR* argv[])
{

	char myC = 'a';
	Uint32 prevTicks = 0;
	Uint32 currentTicks = 0;
	Uint32 prevRotationTicks = 0;
	Uint32 prevLuaTicks = 0;
	bool mustQuit = false, rotate = false;

	SDL_Event event;

	GraphicsManager* gm = new GraphicsManager();
	ResourceManager* rm = new ResourceManager();
	//ObjectManager* om = new ObjectManager();
	om = new ObjectManager();		// ATTENTION : REMETTRE CA EN VARIABLE LOCALE ET REGLER DESIGN POUR ACCES A PARTIR DU LUA
	RenderingManager* rm = new RenderingManager(gm,om);

	om->AddItem(new Tank(400,400,90.0f, "tank1.bmp",om));
	
    LuaHandler luaTest("..\\test.lua", om);
	luaTest.Run();

	while(!mustQuit)
	{
		//luaTest.Run();


		currentTicks = SDL_GetTicks();
		//While there's an event to handle 
		while( SDL_PollEvent( &event ) == 1) 
		{
			switch(event.type)
			{
			case SDL_KEYUP:
				if(event.key.keysym.sym == SDLK_F1)
					mustQuit = true;
				else if(event.key.keysym.sym == SDLK_F2)
					rotate = true;
				break;
			case SDL_QUIT:
				mustQuit = true;
				break;
			default:
				break;
			}
		}

		if( ((currentTicks-prevRotationTicks) > 50) && rotate)
		{
			std::cerr << "Rotation" << std::endl;
			om->RotateItem(1, 10.0);
			std::cerr << om->GetItem(1)->GetSprite()->GetSurface()->h << " " << 
				om->GetItem(1)->GetSprite()->GetSurface()->w << std::endl << " " <<
				om->GetItem(1)->GetSprite()->GetSurface()->offset << " " <<
				 std::endl;
			rotate = false;
			prevRotationTicks = currentTicks;
		}
		
		

		if((currentTicks-prevTicks) > 20)
		{
			//std::cerr << "Render"<<std::endl;
			rm->Render();
			gm->Update();
			prevTicks = currentTicks;
		}

		if((currentTicks-prevLuaTicks) > 1000)
		{
			luaTest.CallLuaFunction("C_LUA_Process") ;
			prevLuaTicks = currentTicks;
		}
	}

	delete om;
	delete rm;
	delete gm;

	return 0;
}

#endif 

#if 0

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
#include <iostream>
#include "stdafx.h"

#include "SDL.h"
#include "SDL_rotozoom.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define START_X 200
#define START_Y 200

#define STATE_STANDING 0
#define STATE_WALKING 1

#define UNIT_SPEED 4

//structures

typedef struct MyPoint
{
	int x, y;
} Point;

typedef struct unit_s
{
	int state;
	double x, y;
	int moving_to_x, moving_to_y;
	double angle;
	int steps;
} unit_t;


Uint16 CreateHicolorPixel(SDL_PixelFormat * fmt, Uint8 red, Uint8 green, Uint8 blue);
void ProcessAngleCoord(Point p, unit_t *unit_s);
void CheckInput(unit_t *unit_s);
void PrintState(unit_t *unit_s);
void RenderCross(SDL_Surface *screen);
void ProcessState(unit_t *unit_s);
void RenderUnit(SDL_Surface *screen, SDL_Surface *unit, unit_t *unit_s);
void Move(unit_t *unit_s);


int exit_loop = 0;
Point last_p;
Uint16 *raw_pixel;

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	SDL_Surface *screen, *unit, *black;
	Uint32 colorkey;
	SDL_Rect dest;
	
	unit_t my_unit;
	
	if (SDL_Init(SDL_INIT_VIDEO))
	{
		printf("Error while initializing SDL\n");
		return 1;
	}
	
	atexit(SDL_Quit);
	
	if (!(screen = SDL_SetVideoMode(400, 400, 16, SDL_DOUBLEBUF | SDL_HWSURFACE)))
	{
		printf("Error while setting Video Mode\n");
		return 1;
	}
	
	if (!(unit = SDL_LoadBMP("unit.bmp")))
	{
		printf("Error while loading unit.bmp\n");
		return 1;
	}
	
	colorkey = SDL_MapRGB(unit->format, 255, 255, 255);
	SDL_SetColorKey(unit, SDL_SRCCOLORKEY | SDL_RLEACCEL, colorkey);
	
	SDL_WM_SetCaption("Rotozoom & all directions moving demo. gamescreators.sourceforge.net", NULL);
	
	raw_pixel = (Uint16 *) screen->pixels;
	
	black = SDL_CreateRGBSurface(SDL_HWSURFACE, 30, 30, 16, 0, 0, 0, 0);
	
	printf("\n\n\n\n\n\n\n\n"); //for correct printing;
	
	my_unit.state = STATE_STANDING;
	my_unit.x = 300;              //unit x and y start position
	my_unit.y = 100;
	my_unit.moving_to_x = 0;
	my_unit.moving_to_y = 0;
	my_unit.angle = 0;
	my_unit.steps = 0;
	
	while(!exit_loop)
	{
		dest.x = my_unit.x - 15;  // 30 / 2 (paint the unit with black)
		dest.y = my_unit.y - 15;
		dest.w = 30;
		dest.h = 30;
		SDL_BlitSurface(black, NULL, screen, &dest);
		
		CheckInput(&my_unit);
		RenderCross(screen);
		ProcessState(&my_unit);
		RenderUnit(screen, unit, &my_unit);
		
		PrintState(&my_unit);
		
		SDL_Flip(screen);
	}
	
	return 0;
}

//****************************************FUNCTIONS****************************************

Uint16 CreateHicolorPixel(SDL_PixelFormat * fmt, Uint8 red, Uint8 green,
			  Uint8 blue)
{
    Uint16 value;

    value = ((red >> fmt->Rloss) << fmt->Rshift) +
	((green >> fmt->Gloss) << fmt->Gshift) +
	((blue >> fmt->Bloss) << fmt->Bshift);

    return value;
}



void ProcessAngleCoord(Point p, unit_t *unit_s)
{
	double hip;
	double y_dist, x_dist;
	
	x_dist = (double)abs(unit_s->x - p.x);
	y_dist = (double)abs(unit_s->y - p.y);
	
	hip = sqrt(x_dist*x_dist + y_dist*y_dist);
	unit_s->angle = acos((x_dist / hip));
	
	unit_s->steps = hip / UNIT_SPEED;
	
	unit_s->angle = unit_s->angle / M_PI * 180;
	
	if ((p.x < unit_s->x) && (p.y <= unit_s->y))
		unit_s->angle = 180 - unit_s->angle;
	if ((p.x <= unit_s->x) && (p.y > unit_s->y))
		unit_s->angle = 180 + unit_s->angle;
	if ((p.x > unit_s->x) && (p.y > unit_s->y))
		unit_s->angle = 360 - unit_s->angle;
	
}


void CheckInput(unit_t *unit_s)
{
	SDL_Event event;
	Uint8 *keystate;
	Point p;
	Uint8 what;
	
	keystate = SDL_GetKeyState(0);

	if (keystate[SDLK_q] || keystate[SDLK_ESCAPE])
			exit_loop = 1;
	
	SDL_PumpEvents();
	what = SDL_GetMouseState(&p.x, &p.y);  //it reacts very slowly. if you know how to make it 
										   //to react quicker, send me an e-mail.
	
	if (last_p.x != p.x || last_p.y != p.y) 	
	{
		last_p.x = p.x;
		last_p.y = p.y;
		
		if (unit_s->state != STATE_WALKING)
		{
			ProcessAngleCoord(p, unit_s);  // calculate the angle so the unit can look at the cursor.
		
			if (what)  //what != 0; key pressed;
			{
				unit_s->state = STATE_WALKING;
				unit_s->moving_to_x = p.x;
				unit_s->moving_to_y = p.y;
			}		
		}
	}
}

void PrintState(unit_t *unit_s)
{
	
	printf("\r\b\r\b\b\r\b\r\b\r\b\r\b\r\b\r\b\r");
	printf("-------------------------\n");
	printf("mouse x = %d\n", last_p.x);
	printf("mouse y = %d\n", last_p.y);
	printf("===unit===\n");
	printf("unit.angle = %lf\n", unit_s->angle); 
	printf("unit.steps = %d\n", unit_s->steps);
	printf("unit.x = %lf   unit.y = %lf\n", unit_s->x, unit_s->y);
	printf("unit.moving_to_x = %d   unit.moving_to_y = %d\n", unit_s->moving_to_x, unit_s->moving_to_y);
	
	
}

void RenderCross(SDL_Surface * screen)
{
	int i, offset;
	Uint16 pixel_color;
	
	pixel_color = CreateHicolorPixel(screen->format, 255, 255, 255); //white cross
	
	for(i = 0;i<400;i++)
	{
		offset = (screen->pitch / 2 * START_Y + i); //horizontal line
		raw_pixel[offset] = pixel_color;
	}
	
	for(i = 0;i<400;i++)
	{
		offset = (screen->pitch / 2 * i + START_X); //vertical line
		raw_pixel[offset] = pixel_color;
	}
	
}

void ProcessState(unit_t *unit_s)
{
	switch(unit_s->state)
	{
		case STATE_STANDING:
			//AnimateStanding
		break;
		
		case STATE_WALKING:
			Move(unit_s);
			//AnimateWalking;
		break;
	}
}


void RenderUnit(SDL_Surface * screen, SDL_Surface *unit, unit_t *unit_s)
{
	SDL_Surface *temp;
	SDL_Rect dest;
	
	temp = rotozoomSurface(unit, unit_s->angle, 1, 1);
	
	dest.x = (unit_s->x - (temp->w/2)); //get center of rotozoomed surface.
	dest.y = (unit_s->y - (temp->h/2));
	dest.w = temp->w;
	dest.h = temp->h;
	
	SDL_BlitSurface(temp, NULL, screen, &dest);
	
}



void Move(unit_t *unit_s)
{
	unit_s->x += UNIT_SPEED * cos(unit_s->angle * M_PI / 180); //calculate moving speed and direction
	unit_s->y -= UNIT_SPEED * sin(unit_s->angle * M_PI / 180); 
	
	unit_s->steps --;
	
	if (unit_s->steps <= 0)
	{
		unit_s->state = STATE_STANDING;
	}
}

#endif
